﻿using System;
using System.Drawing;
using AForge.Imaging;
using System.Drawing.Imaging;
using System.Collections.Generic;
using BrainTechLLC.ImageOperators;
using BrainTechLLC;
using System.Diagnostics;
using AForge.Imaging.Filters;

namespace BrainTechLLC.FilterExtensions
{    
    public abstract partial class SingleFilterBase : BaseNotifyPropertyChanged, IObjectLock, ISingleFilter
    {
        protected object _lockObj = new object();
        protected IFilter _filter;
        
        protected FilterStatus _status;
        protected string _filterTypeName;

        [NonSerialized]
        protected FastSmartWeakEvent<EventHandler<ObjectEventArgs<Bitmap, string, string, ISingleFilter>>> _beforeFilterBitmap = new FastSmartWeakEvent<EventHandler<ObjectEventArgs<Bitmap, string, string, ISingleFilter>>>();
        public event EventHandler<ObjectEventArgs<Bitmap, string, string, ISingleFilter>> BeforeFilterBitmap { add { _beforeFilterBitmap.Add(value); } remove { _beforeFilterBitmap.Remove(value); } }

        [NonSerialized]
        protected FastSmartWeakEvent<EventHandler<ObjectEventArgs<Bitmap, string, string, ISingleFilter>>> _afterFilterBitmap = new FastSmartWeakEvent<EventHandler<ObjectEventArgs<Bitmap, string, string, ISingleFilter>>>();
        public event EventHandler<ObjectEventArgs<Bitmap, string, string, ISingleFilter>> AfterFilterBitmap { add { _afterFilterBitmap.Add(value); } remove { _afterFilterBitmap.Remove(value); } }

        public object LockObject { get { return _lockObj; } }

        [NonSerialized]
        protected Type _filterType;

        public virtual Type FilterType
        {
            get
            {
                if (_filterType == null)
                {
                    this.Locked(() => _filterType = AllFilters.FindFilter(_filterTypeName), () => _filterType == null);
                }
                return _filterType;
            }
            set
            {
                if (_filterType != value)
                {
                    _filterType = value;
                    OnPropertyChanged("FilterType");
                }
            }
        }

        public virtual IFilter Filter
        {
            get
            {
                if (_filter == null)
                {
                    this.Locked(() =>
                    {
                        Type t = FilterType;

                        if (t != null)
                        {
                            try { _filter = t.CreateFilter(); }
                            catch
                            {
                                Console.WriteLine("BLAH: " + t.Name);
                                _filter = null;
                            }
                        }
                    }, () => _filter == null);
                }
                return _filter;
            }
            set
            {
                if (_filter != value)
                {
                    _filter = value;

                    if (value != null)
                    {
                        FilterType = value.GetType();
                    }

                    if (_filterType != null)
                    {
                        FilterTypeName = _filterType.Name;
                    }

                    OnPropertyChanged("Filter");
                }
            }
        }

        public virtual FilterStatus Status
        {
            get { return _status; }
            set
            {
                if (_status != value)
                {
                    bool oldDisabled = Disabled;

                    _status = value;
                    OnPropertyChanged("Status");

                    bool newDisabled = Disabled;

                    if (oldDisabled != newDisabled)
                    {
                        OnPropertyChanged("Disabled");
                    }
                }
            }
        }

        public virtual string FilterTypeName
        {
            get { return _filterTypeName; }
            set
            {
                if (_filterTypeName != value)
                {
                    _filterTypeName = value;
                    OnPropertyChanged("FilterTypeName");
                }
            }
        }

        public virtual bool Disabled
        {
            get
            {
                return (((_status & FilterStatus.Disabled) == FilterStatus.Disabled ||
                        (_status & FilterStatus.TempNotActive) == FilterStatus.TempNotActive) &&
                        (_status & FilterStatus.TempActive) != FilterStatus.TempActive);
            }
        }        
    }
}
